home *** CD-ROM | disk | FTP | other *** search
- Subject: v13i098: Multi-user conferencing system, Part01/05
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Keith Gabryelski <ag@crash.cts.com>
- Posting-number: Volume 13, Issue 98
- Archive-name: conf/part01
-
-
- [ I did not repackage this into the more common 60K chunks.
- Porting to V7 doesn't look too tough -- look for the three-arg
- open() calls. --r$ ]
-
- Conf is a line oriented multi-user chat program designed to work on any
- SysV, BSD, or Xenix system.
-
- Conf has several advantages over the standard write program supplied
- with most Unix and Xenix operating systems.
-
- o Unlimited users conferencing at once.
-
- o 100 separate discussion lines.
-
- o Public and private messages in addition to password
- encrypted messages.
-
- o Quick and efficient user interaction.
-
- o User definable formats for messages.
-
- o Intelligent message display algorithm.
- --------------------------------------------------------------------
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # MANIFEST
- # Makefile
- # conf.c
- # conf.el
- export PATH; PATH=/bin:$PATH
- if test -f 'MANIFEST'
- then
- echo shar: will not over-write existing file "'MANIFEST'"
- else
- cat << \SHAR_EOF > 'MANIFEST'
- A Manifest Archived in
- ------------------------------------------------------------------------
- MANIFEST 1
- Makefile 1
- conf.c 1
- conf.el 1
- conf.h 2
- confalloc.c 2
- config.h 2
- confopts.c 2
- confprnt.c 3
- confrots.c 3
- confrw.c 3
- confsig.c 4
- confstr.c 4
- extern.h 4
- structs.h 4
- doc/READ_ME 5
- doc/conf.1 5
- doc/conf.txt 5
- doc/confhelp 5
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- cat << \SHAR_EOF > 'Makefile'
- SHELL=/bin/sh
- INSTALL= mv
- CFLAGS= -g
- SRCS= conf.c confrw.c confrots.c confopts.c confalloc.c confstr.c confprnt.c confsig.c
- OBJS= conf.o confrw.o confrots.o confopts.o confalloc.o confstr.o confprnt.o confsig.o
- HEDRS= conf.h config.h extern.h structs.h
- NEW= xconf
- NAME= conf
- LISP= conf.el
- MAKES= Makefile
- DOCDIR= doc
- CONFLIB= /usr/lib/conf
- BINDIR= /usr/local/bin
- LINT=lint
-
- LIBS= -ltermlib
-
- $(NEW): $(OBJS)
- $(CC) $(CFLAGS) -o $(NEW) $(OBJS) $(LIBS)
-
- clean:
- rm -f *.o $(NEW) core
-
- shar:
- shar $(DOCDIR) $(MAKES) $(SRCS) $(HEDRS) $(LISP) > conf.shar
-
- lint:
- $(LINT) $(LIBS) $(SRCS)
-
- install:
- cp $(NEW) $(BINDIR)/$(NAME)
- -mkdir $(CONFLIB)
- cp $(DOCDIR)/confhelp $(CONFLIB)
- -chmod 777 $(CONFLIB)
- -chmod 644 $(CONFLIB)/*
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'conf.c'
- then
- echo shar: will not over-write existing file "'conf.c'"
- else
- cat << \SHAR_EOF > 'conf.c'
- /*
- * conf - An interactive multi-user chat program.
- *
- * conf Copyright (c) 1986, 1987 by Keith Gabryelski
- *
- * Conf is quasi-public domain software; it may be used and copied
- * freely and may be modified to suit the indivuals needs as long
- * as:
- *
- * [1] It is not sold.
- * [2] It is not made part of any licensed product.
- * [3] This header and others like it are not modified or removed.
- * [4] You allow others to use and copy without charge.
- *
- * without expressed written permission from the original
- * author (Keith Gabryelski).
- *
- *
- */
-
- #include "conf.h"
-
- char *progname; /* program name (argv[0]) */
- char *logname, *homedir;
- int log_rfd, log_wfd, usr_fd;
- long ourplace;
- FILE *rec_fp;
- int confing = FALSE;
-
- char pubkey[MAXPASSWORDLEN], curkey[MAXPASSWORDLEN];
- char pubblock[MAXPASSWORDLEN*8], curblock[MAXPASSWORDLEN*8];
- char pubpass[MAXPASSWORDLEN], curpass[MAXPASSWORDLEN];
-
- char replyname[MAXNAMELEN] = "";
- char replytty[MAXTTYLEN+1] = ""; /* there is a reason for the + 1
- although I have forgotten it
- right now, I'm sure it should
- be there.
- */
-
- char *wrdata;
- unsigned wdlen=0;
-
- struct cusrfil cuser, tuser;
- struct clogfil clog, tlog;
-
- #ifdef SYSV
- struct termio term, saveterm;
- #endif SYSV
-
- #ifdef BSD
- struct tchars chrstr;
- struct sgttyb ktty;
- int ttyflags;
- #endif BSD
-
- char ichar = CTRL(C); /* interrupt character */
- char qchar = CTRL(\\); /* quit character */
-
- jmp_buf env;
-
- int columns = DEF_COLUMNS, lines = DEF_LINES;
- int banner = TRUE, seeme = TRUE, informe = FALSE, warncrypt = TRUE;
- int autowho = FALSE, lineinput = FALSE, beep = FALSE, askdump = TRUE;
- int expand8bit = TRUE, expandctrl = TRUE;
-
- char *cls, *pager, *shell, *normform, *lineform, *shoutform, *sendform;
- char *informform, *recfile;
-
- my_int()
- {
- longjmp(env, 1);
- }
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char *ptr, *word, *line;
- int num, x, old_umask;
- struct passwd *pt;
-
- /* set up some pointers to interesting stuff */
- wrdata = mymalloc(wdlen = PAGESIZ);
-
- progname = *argv++; argc--;
- cuser.cu_line = 1;
- cuser.cu_flags = USER_ON;
- cuser.cu_procid = getpid();
-
- pt = getpwuid(getuid());
-
- if ((ptr = getlogin()) == NULL)
- if ((ptr = pt->pw_name) == NULL)
- ptr = "???"; /* can't figure this guy out */
-
- logname = mymalloc((unsigned)(strlen(ptr)+1));
- (void) strcpy(logname, ptr);
-
- (void) strcpy(cuser.cu_cname, ptr);
- (void) strcpy(cuser.cu_tty, ((ptr= strrchr(ttyname(0), '/')) ? ptr+1 : "tty??"));
-
- homedir = mymalloc((unsigned)(strlen(pt->pw_dir)+1));
- (void) strcpy(homedir, pt->pw_dir);
-
- zbuf(pubkey, MAXPASSWORDLEN);
- (void)strncpy(pubkey, DEF_KEY, MAXPASSWORDLEN);
- zbuf(curkey, MAXPASSWORDLEN);
- (void)strncpy(curkey, DEF_KEY, MAXPASSWORDLEN);
-
- cls = mymalloc((unsigned)(strlen(DEF_CLS)+1));
- (void) strcpy(cls, DEF_CLS);
-
- normform = mymalloc((unsigned)(strlen(DEF_FORM_NORM)+1));
- (void) strcpy(normform, DEF_FORM_NORM);
-
- sendform = mymalloc((unsigned)(strlen(DEF_FORM_SEND)+1));
- (void) strcpy(sendform, DEF_FORM_SEND);
-
- shoutform = mymalloc((unsigned)(strlen(DEF_FORM_SHOUT)+1));
- (void) strcpy(shoutform, DEF_FORM_SHOUT);
-
- informform = mymalloc((unsigned)(strlen(DEF_FORM_INFORM)+1));
- (void) strcpy(informform, DEF_FORM_INFORM);
-
- lineform = mymalloc((unsigned)(strlen(DEF_FORM_LINE)+1));
- (void) strcpy(lineform, DEF_FORM_LINE);
-
- pager = mymalloc((unsigned)(strlen(DEF_PAGER)+1));
- (void) strcpy(pager, DEF_PAGER);
-
- shell = mymalloc((unsigned)(strlen(DEF_SHELL)+1));
- (void) strcpy(shell, DEF_SHELL);
-
- recfile = mymalloc((unsigned)(strlen(DEF_RECFILE)+1));
- (void) strcpy(recfile, DEF_RECFILE);
-
- gettcap(); /* get termcap stuff */
- getrc(); /* get some defaults from rc file */
- getopts(); /* get some defaults from environment */
-
- while (word = *argv++, argc--)
- {
- if (*word == '-')
- {
- word++;
- while (*word != '\0')
- {
- switch(*word++)
- {
- case 'l':
- if (*word == '\0')
- {
- if (!argc)
- {
- (void)printf("%s: -l switch specified without a conference line number\n",
- progname);
- usage();
- }
- word = *argv++; --argc;
- }
-
- num = atoi(word);
- if ((num < 1) || (num > MAXCONFLINES))
- {
- (void)printf("%s: invalid conference line number: %d\n",
- progname, num);
- usage();
- }
- cuser.cu_line = num;
- *word = '\0';
- break;
-
- case 's':
- if (*word == '\0')
- {
- if (!argc)
- {
- (void)fprintf(stderr, "%s: -s specified without a parameter\n", progname);
- usage();
- }
- word = *argv++; --argc;
- }
-
- if ((x = setopts(parsestr(word, strlen(word), NEXTWORD))) != FOUNDOPT)
- {
- char *errmess;
-
- if (x == AMBIGUOUS)
- errmess = "Ambiguous";
- else
- errmess = "Invalid";
-
- (void)fprintf(stderr, "%s: %s -s parameter: %s\n",
- progname, errmess, word);
- usage();
- }
- *word = '\0';
- break;
-
- case 'w':
- (void) do_who(0);
- (void) exit(0);
-
- default:
- (void)fprintf(stderr, "%s: invalid parameter '%c'\n",
- progname, *(word-1));
- usage();
- }
- }
- }
- else
- (void) do_ring(word);
- }
-
- /* by this point, all parameters/options have been parsed */
-
- confing = TRUE;
-
- makepass(pubkey, pubblock, pubpass);
- makepass(curkey, curblock, curpass);
-
- clog.f_line = cuser.cu_line;
- clog.f_usrlen = strlen(cuser.cu_cname) + 1;
- clog.f_ttylen = strlen(cuser.cu_tty) + 1;
-
- old_umask = umask(0);
-
- if ((usr_fd = open(CONFUSERS, O_RDWR|O_CREAT, FILEMASK)) < 0)
- {
- (void)fprintf(stderr, "%s: couldn't open %s (%s)\n", progname,
- CONFUSERS, puterr(errno));
- (void) exit(-1);
- }
-
- (void)lseek(usr_fd, 0L, 0);
-
- #ifdef SYSV
- lockf(usr_fd, F_LOCK, 0L); /* lock user file */
- #endif SYSV
-
- #ifdef BSD
- flock(usr_fd, LOCK_EX);
- #endif BSD
-
- ourplace = lseek(usr_fd, 0L, 1);
- while (read(usr_fd, (char *)&tuser, sizeof(struct cusrfil)) ==
- sizeof(struct cusrfil))
- if (tuser.cu_flags == USER_OFF)
- break;
- else
- ourplace = lseek(usr_fd, 0L, 1);
-
- (void)lseek(usr_fd, ourplace, 0);
-
- write(usr_fd, (char *)&cuser, sizeof(struct cusrfil));
-
- #ifdef SYSV
- (void)lseek(usr_fd, 0L, 0);
- lockf(usr_fd, F_ULOCK, 0L);
- #endif SYSV
-
- #ifdef BSD
- flock(usr_fd, LOCK_UN);
- #endif BSD
-
- if ((log_wfd = open(CONFLOG, O_WRONLY|O_CREAT|O_APPEND, FILEMASK)) < 0)
- {
- (void)fprintf(stderr,"%s: couldn't create/open %s for writing(%s)\n",
- progname, CONFLOG, puterr(errno));
- (void) exit(-1);
- }
-
- (void) umask(old_umask);
-
- if ((log_rfd = open(CONFLOG, O_RDONLY)) < 0)
- {
- (void)fprintf(stderr,"%s: couldn't open %s for reading (%s)\n",
- progname, CONFLOG, puterr(errno));
- (void) exit(-1);
- }
-
- /* any fatal errors pass this point must do a nice_exit(status) */
-
- (void)lseek(log_rfd, 0L, 2);
- write_log(INFORM, "Login", (char *)NULL, 0, (unsigned)strlen("Login"));
-
- #ifdef SYSV
- (void) ioctl(0, TCGETA, &term);
- saveterm=term;
-
- if (!(term.c_lflag&ECHO))
- lineinput = TRUE;
-
- ichar = term.c_cc[VINTR];
- qchar = term.c_cc[VQUIT];
-
- term.c_iflag &= ~(ICRNL);
- term.c_lflag &= ~(ICANON|ECHO);
- term.c_cc[VEOF] = 1;
- term.c_cc[VEOL] = 0;
- (void) ioctl(0, TCSETAW, &term);
- #endif SYSV
-
- #ifdef BSD
- gtty(0, &ktty);
- ttyflags = ktty.sg_flags;
-
- if (!(ttyflags&ECHO))
- lineinput = TRUE;
-
- ktty.sg_flags |= CBREAK;
- ktty.sg_flags &= ~ECHO;
- stty(0, &ktty);
-
- (void) ioctl(0, TIOCGETC, &chrstr);
- ichar = chrstr.t_intrc;
- qchar = chrstr.t_quitc;
- #endif BSD
-
- (void)signal(SIGINT, SIG_IGN);
- (void)signal(SIGQUIT, fatal);
- (void)signal(SIGHUP, nice_exit);
- (void)signal(SIGTERM, nice_exit);
- (void)signal(SIGILL, fatal);
- (void)signal(SIGTRAP, fatal);
- (void)signal(SIGIOT, fatal);
- (void)signal(SIGEMT, fatal);
- (void)signal(SIGFPE, fatal);
- (void)signal(SIGBUS, fatal);
- (void)signal(SIGSEGV, fatal);
- (void)signal(SIGSYS, fatal);
- (void)signal(SIGPIPE, fatal);
-
- if (banner)
- (void) version(FALSE);
-
- if (autowho)
- {
- (void) printf("Currently on %s:\n\n", progname);
- (void) do_who(0);
- (void) putchar('\n');
- }
-
- (void)printf("login user %s (%s) on conference line %d\n",
- cuser.cu_cname, cuser.cu_tty, cuser.cu_line);
-
- if (setjmp(env))
- {
- (void)signal(SIGINT, my_int);
- dispchar(ichar, stdout, NOVIS);
- (void)putchar('\n');
- (void)lseek(log_rfd, 0L, 2);
- }
- else
- (void)signal(SIGINT, my_int);
-
- forever
- {
- read_log();
-
- line = getline();
- (void)signal(SIGINT, my_int);
- if (line != NULL)
- {
- if ((*line == ':') && (*(line+1) != ':'))
- {
- if (*(line+1) == '!')
- keep_shell(line+2);
- else
- {
- --linelen;
- (void) intpret(line+1);
- }
- }
- else
- {
- if (*line == ':')
- write_log(NORMAL, line+1, (char *)NULL, 0, linelen-1);
- else
- write_log(NORMAL, line, (char *)NULL, 0, linelen);
- }
- free(line);
- }
- }
- }
-
- nice_exit(status)
- int status;
- {
- make_nice(TRUE);
-
- (void)signal(SIGALRM, SIG_DFL);
- (void)signal(SIGINT, SIG_DFL);
- (void)signal(SIGQUIT, SIG_DFL);
- (void)signal(SIGHUP, SIG_DFL);
- (void)signal(SIGTERM, SIG_DFL);
- (void)signal(SIGILL, SIG_DFL);
- (void)signal(SIGTRAP, SIG_DFL);
- (void)signal(SIGIOT, SIG_DFL);
- (void)signal(SIGEMT, SIG_DFL);
- (void)signal(SIGFPE, SIG_DFL);
- (void)signal(SIGBUS, SIG_DFL);
- (void)signal(SIGSEGV, SIG_DFL);
- (void)signal(SIGSYS, SIG_DFL);
- (void)signal(SIGPIPE, SIG_DFL);
-
- (void) exit(status);
- }
-
- make_nice(status)
- int status;
- {
- int c, rotten_egg; /* last one out ... */
-
- (void)alarm(0);
-
- if (status)
- write_log(INFORM,"Logout",(char *)NULL,0, (unsigned)strlen("Logout"));
-
- if (cuser.cu_flags&USER_RECORD)
- (void)fclose(rec_fp);
-
- cuser.cu_flags = USER_OFF;
- write_usr();
-
- (void)lseek(usr_fd, 0L, 0);
-
- #ifdef SYSV
- lockf(usr_fd, F_LOCK, 0L); /* lock user file */
- #endif SYSV
-
- #ifdef BSD
- flock(usr_fd, LOCK_EX);
- #endif BSD
-
- rotten_egg = TRUE;
- while (read(usr_fd, (char *)&tuser, sizeof(struct cusrfil)) ==
- sizeof(struct cusrfil))
- if (tuser.cu_flags != USER_OFF)
- {
- c = kill(tuser.cu_procid, 0);
- if ((!c) || ((c < 0) && (errno != ESRCH)))
- rotten_egg = FALSE;
- }
-
- if (rotten_egg)
- {
- if (unlink(CONFLOG) < 0)
- (void)printf("%s: couldn't remove %s (%s)\n", progname, CONFLOG,
- puterr(errno));
-
- if (unlink(CONFUSERS) < 0)
- (void)printf("%s: couldn't remove %s (%s)\n", progname, CONFUSERS,
- puterr(errno));
- }
-
- #ifdef SYSV
- (void)lseek(usr_fd, 0L, 0);
- lockf(usr_fd, F_ULOCK, 0L);
- #endif SYSV
-
- #ifdef BSD
- flock(usr_fd, LOCK_UN);
- #endif BSD
-
- (void)close(usr_fd);
- (void)close(log_rfd);
- (void)close(log_wfd);
-
- #ifdef SYSV
- (void) ioctl(0, TCSETAW, &saveterm);
- #endif SYSV
-
- #ifdef BSD
- ktty.sg_flags = ttyflags;
- stty(0, &ktty);
- #endif BSD
- }
-
- usage()
- {
- (void)fprintf(stderr, "usage: %s [-w][-s switchname][-l line-number]\n",
- progname);
- (void) exit(-1);
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'conf.el'
- then
- echo shar: will not over-write existing file "'conf.el'"
- else
- cat << \SHAR_EOF > 'conf.el'
- ;; Run conf(1) as asynchronous inferior of Emacs.
- ;; provided by Michael Ditto (ford@kenobi.cts.com)
- ;; This file is not part of GNU Emacs.
-
- (defvar conf-process nil "The process of conf.")
-
- (defun conference (switches)
- "Conference with other users."
- (interactive "sArgs to conference (switches): ")
-
- (require 'shell)
-
- (let ((buffer (get-buffer-create "*conference*")))
- (switch-to-buffer buffer)
-
- (if (get-buffer-process buffer)
- (error "A conference process is already running"))
-
- (setq conf-process
- (start-process "conf" buffer
- "/bin/sh" "-c" (format "conf %s" switches))))
-
- (shell-mode)
- (turn-on-auto-fill)
- (setq mode-name "Conference")
- (set-marker (process-mark conf-process) (point-max))
- (set-process-filter conf-process 'conf-filter))
-
- (defun conf-filter (process string)
- (save-excursion
- (set-buffer (process-buffer process))
- (goto-char (process-mark process))
- (let ((start-line (point)))
- (insert-before-markers string)
- ;; (fill-region start-line (point))
- )
-
- (if (get-buffer-window (process-buffer process))
- nil
- (beep t))))
- SHAR_EOF
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-